#pragma once
#include <iostream>
#include <fstream>
#include <cstdio>
#include <string>
#include <ctime>
#include <cstdarg>
#include <sys/types.h>
#include <unistd.h>
#include "LockGuard.hpp"
bool gIsSave = false;

std::string logname = "log.txt";
std::string trashname = "trash.txt";

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

// 1. 日志是由等级的
enum Level
{
    DEBUG = 0,
    INFO,
    WARNING,
    ERROR,
    FATAL
};

std::string LevelToString(int level)
{
    switch (level)
    {
    case DEBUG:
        return "DEBUG";
    case INFO:
        return "INFO";
    case WARNING:
        return "WARNING";
    case ERROR:
        return "ERROR";
    case FATAL:
        return "FATAL";
    default:
        return "UNKOWN";
    }
}

void Savefile(std::string &filename, std::string &message)
{
    std::ofstream out(filename, std::ios::app);
    if (!out.is_open())
    {
        return;
    }
    out << message;
    out.close();
}

std::string Gettime()
{
    time_t currtime = time(nullptr);
    struct tm *fromatetime = localtime(&currtime);
    if (fromatetime == nullptr)
    {
        return "ERROR";
    }
    char buffer[1024];
    snprintf(buffer, sizeof(buffer), "%d-%d-%d-%d-%d-%d",
             fromatetime->tm_year + 1900,
             fromatetime->tm_mon + 1,
             fromatetime->tm_mday,
             fromatetime->tm_hour,
             fromatetime->tm_min,
             fromatetime->tm_sec);
    return buffer;
}

void Logmessage(int level, int line, std::string filename,  const char *format, ...)
{
    std::string clevel = LevelToString(level);
    std::string time = Gettime();
    pid_t selfpid = getpid();
    va_list arg;
    char buffer[1024];
    va_start(arg, format);
    vsnprintf(buffer, sizeof(buffer), format, arg);
    va_end(arg);

    std::string message = "[" + time + "]" + "[" + clevel + "]" +
                          "[" + std::to_string(selfpid) + "]" +
                          "[" + filename + "]" + "[" + std::to_string(line) + "] " + buffer + "\n";
    LookGuard Lookguard(&lock);
    if (!gIsSave)
    {
        std::cout<<message<<std::endl;
    }
    else
    {
        Savefile(logname, message);
    }
}
void LogTrashmessage(int level, int line, std::string filename,  const char *format, ...)
{
    std::string clevel = LevelToString(level);
    std::string time = Gettime();
    pid_t selfpid = getpid();
    va_list arg;
    char buffer[1024];
    va_start(arg, format);
    vsnprintf(buffer, sizeof(buffer), format, arg);
    va_end(arg);

    std::string message = "[" + time + "]" + "[" + clevel + "]" +
                          "[" + std::to_string(selfpid) + "]" +
                          "[" + filename + "]" + "[" + std::to_string(line) + "] " + buffer + "\n";
    LookGuard Lookguard(&lock);
        Savefile(trashname, message);
    
}

#define LOG(level,format,...) do{Logmessage(level,__LINE__,__FILE__,format,##__VA_ARGS__);}while(0)//c99新增处理可变参数+##支持没有可变参数时 代码块整体替换 do while(0)
#define LOGINTRASH(level,format,...) do{LogTrashmessage(level,__LINE__,__FILE__,format,##__VA_ARGS__);}while(0)//c99新增处理可变参数+##支持没有可变参数时 代码块整体替换 do while(0)
#define EnableFile() do{gIsSave=true;}while(0)
#define Enablescreem() do{gIsSave=false;}while(0)
// void LOG(int level, const char *format, ...) {
//     va_list args;
//     va_start(args, format);
    
//     // 由于__FILE__是预处理器宏，所以在这里传递
//     std::string filename = __FILE__;

//     char formatted_message[1024];
//     vsnprintf(formatted_message, sizeof(formatted_message), format, args);
//     va_end(args);

//     Logmessage(level, __LINE__, filename, gIsSave, "%s", formatted_message);
// }
// void EnableFile()
// {
//     gIsSave = true;
// }
// void EnableScreen()
// {
//     gIsSave = false;
// }
// class log()
// {
// public:
//     log()
//     {
//     }
//     ~log()
//     {
//     }

// private:
//     std::string _filename;
//     int _style;
// };
